#include <iostream>
#include <ctime>
#include "miniutil/md5.h"
#include "miniutil/random.h"
#include "miniutil/compress.h"
#include "minitest/testcase.h"

using namespace miniutil;


class compresstest : public testcase
{
public:
    compresstest()
    {
        psrcbuf = NULL;
        psrclen = 0;
        pdestbuf = NULL;
        pdestlen = 0;
    }

    void generatesource(int len)
    {
        if(psrcbuf != NULL)
            delete []psrcbuf;
        psrclen = len;
        psrcbuf = new char[len];
        for(int i=0; i< len; i++)
        {
            psrcbuf[i] = (miniutil::Random::rand_value(0x10)&0xFF);
        }
    }

    int generatesourcefromfile(std::string fn)
    {
        if(psrcbuf != NULL)
            delete []psrcbuf;
        FILE* pfile = fopen(fn.c_str(), "rb");
        if(pfile == NULL)
            return -1;
        fseek(pfile, 0, SEEK_END);
        psrclen = ftell(pfile);
        fseek(pfile, 0, SEEK_SET);
        
        psrcbuf = new char[psrclen];
        fread(psrcbuf, psrclen, 1, pfile);
        return 0;
    }

    int savesource(std::string fn, const char* pbuf, int len)
    {
        if(pbuf != NULL)
        {
            FILE* pfile = fopen(fn.c_str(), "wb+");
            fwrite(pbuf, len, 1, pfile);
            fclose(pfile);
        }
        return 0;

    }

    virtual void test()
    {
        //generatesource(2000000);
        generatesourcefromfile("a.mt");
        std::cout<<"MD5:"<<miniutil::MD5::hex_digest(psrcbuf, psrclen)<<std::endl;
        time_t now = time(NULL);
        std::cout<<ctime(&now)<<std::endl;
        miniutil::util::Compress::MemEncode(psrcbuf, psrclen, &pdestbuf, &pdestlen);
        now = time(NULL);
        std::cout<<ctime(&now)<<std::endl;
        std::cout<<"from "<<psrclen<<" to "<<pdestlen<<std::endl;

        savesource("x.zip", pdestbuf, pdestlen);

        char* returnvle = NULL;
        int returnlen = 0;
        now = time(NULL);
        std::cout<<ctime(&now)<<std::endl;
        miniutil::util::Compress::MemDecode(pdestbuf, pdestlen, &returnvle, &returnlen);
        now = time(NULL);
        std::cout<<ctime(&now)<<std::endl;
        std::cout<<"decompress length:"<<returnlen<<std::endl;
        std::cout<<"MD5:"<<miniutil::MD5::hex_digest(returnvle, returnlen)<<std::endl;

        savesource("y.unzip", returnvle, returnlen);

        for(int i=0; i< psrclen; i++)
        {
            if(returnvle[i] != psrcbuf[i])
                std::cout<<"ERROR!!"<<std::endl;
        }

        delete []pdestbuf;
        delete []returnvle;

    }

    char *psrcbuf;
    int psrclen;
    char *pdestbuf;
    int pdestlen;
};

testcase * ptestcompress = new compresstest();
